001 /**
002 * Created by IntelliJ IDEA.
003 * User: Wei Wang
004 * Date: Nov 30, 2002
005 * Time: 2:13:56 PM
006 */
007
008 package EVolve.visualization.XYViz.ValValViz;
009
010 import EVolve.util.*;
011 import EVolve.util.painters.RandomPainter;
012 import EVolve.data.*;
013 import EVolve.visualization.*;
014 import EVolve.visualization.Dimension;
015 import EVolve.Scene;
016 import javax.swing.*;
017 import java.util.*;
018 import java.awt.event.*;
019 import java.awt.*;
020
021 public class StackViz extends ValueValueVisualization{
022 private ArrayList menuList;
023 private JMenuItem itemChangeThread;
024 private HashMap methodStacks;
025 private ThreadChooser td;
026 private JTextField textBegin, textEnd;
027 private Stack stack;
028 private int event;
029 private JMenuItem itemSelectTimeFrame, itemSelectOccurredEntities;
030 private static JMenuItem selectionMenu[] = null;
031 private String selected;
032 protected static int SELECT_OPTION = 0x0011;
033 private JLabel toEventNo;
034
035
036 public StackViz() {
037 super();
038
039 menuList = new ArrayList();
040 imageMap = new HashMap();
041 methodStacks = new HashMap();
042 td = new ThreadChooser(imageMap,false);
043
044 interval = 1;
045 beginCall = 0;
046 endCall = 300;
047 }
048
049 public Dimension[] createDimension() {
050 Dimension [] returnDimension = new Dimension[3];
051
052 xAxis = new ValueDimension();
053 entityIdFilter = new ReferenceDimension();
054 filter2 = new ReferenceDimension();
055
056 returnDimension[0] = xAxis;
057 returnDimension[1] = entityIdFilter;
058 returnDimension[2] = filter2;
059
060 return returnDimension;
061 }
062
063 protected void updateConfiguration() {
064 try {
065 beginCall = Integer.parseInt(textBegin.getText());
066 endCall = Integer.parseInt(textEnd.getText());
067
068 canvas.setName("Time - Invocations", "Stack");
069 super.updateConfiguration();
070 } catch (NumberFormatException e) {
071 Scene.showErrorMessage("Begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+".");
072 configure();
073 };
074 }
075
076 public HashMap getCurrentConfigure() {
077 HashMap configure = super.getCurrentConfigure();
078
079 configure.put("Interval", new Integer(interval));
080 configure.put("BeginCall", new Long(beginCall));
081 configure.put("EndCall", new Long(endCall));
082
083 return configure;
084 }
085
086 public void preVisualize() {
087 xMax = 0;
088 event = 0;
089 stack = null;
090 image = null;
091 imageMap.clear();
092 methodStacks.clear();
093 currentThread = -1;
094 getSelection();
095 installPainter();
096 super.preVisualize();
097 }
098
099 public void receiveElement(Element element) {
100 long methodId = entityIdFilter.getField(element);
101 long threadId = filter2.getField(element);
102 long callno = xAxis.getField(element) - 1;
103
104 countEvents(callno/2);
105
106 switchThread(threadId);
107
108 if ((callno<beginCall*2) || (callno>endCall*2+1)) {
109 if (element.isOptional()) {// method return;
110 if (!stack.empty()) stack.pop();
111 } else
112 stack.push(new Long(methodId));
113 return;
114 }
115
116 event++;
117 if (!element.isOptional()) // method enter;
118 stack.push(new Long(methodId));
119
120 for (int j=0;j<stack.size();j++) {
121 painter.paint(image,callno-beginCall*2,j,((Long)stack.get(j)).intValue());
122 }
123
124 if (element.isOptional()) {// method return;
125 if (!stack.empty()) stack.pop();
126 }
127 }
128
129 public void visualize() {
130 if (imageMap.size() == 0 ) return;
131 while (selected==null) {
132 selected = td.showDialog();
133 if (selected != null) {
134 image = (AutoImage)imageMap.get(new Long(selected.substring(7,selected.length())));
135 canvas.setName("Time - "+ xAxis.getDataFilter().getName() + "(" + event/2 +" events)", "Stack");
136 sort();
137 selected = null;
138 break;
139 }
140 }
141 }
142
143 public void makeSelection() {
144 if (SELECT_OPTION == 0) {
145 Scene.showErrorMessage("No data is to be selected.");
146 return;
147 }
148
149 if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
150 Scene.showErrorMessage("The active data source used currently is different from \n" +
151 "this visualization, please choose \"" +
152 Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
153 return;
154 }
155
156 int x1 = canvas.getStartX();
157 int x2 = canvas.getEndX();
158 int y1 = canvas.getEndY();
159 int y2 = canvas.getStartY();
160
161 if (!normalOrientation) {
162 int temp;
163 temp = x1;
164 x1 = y1;
165 y1 = temp;
166 temp = x2;
167 x2 = y2;
168 y2 = temp;
169 }
170
171 if (((x1<0)&&(x2<0)) || ((x1/2>=timeMap.size()))&&(x2/2>=timeMap.size()))
172 return;
173
174 if (x1 < 0) x1 = 0;
175
176 if (x2/2 > timeMap.size())
177 x2 = (timeMap.size()-1)*2;
178
179
180 long start, end;
181 if ((SELECT_OPTION & 0x000f) == 0) {
182 start = 0;
183 end = Long.MAX_VALUE;
184 } else {
185 long eventInterval[] = (long[])timeMap.get((int)(x1/2+beginCall));
186 start = eventInterval[1];
187 eventInterval = (long[])timeMap.get((int)(x2/2+beginCall));
188 end = eventInterval[1];
189 }
190
191 if (y1 < 0) y1 = 0;
192
193 int methodId;
194 ArrayList idList = new ArrayList();
195 for (int i = x1; i <= x2; i++) {
196 for (int j = y1; j <= y2; j++) {
197 if (normalOrientation)
198 methodId = (int)getEntityId(i,j);
199 else
200 methodId = (int)getEntityId(j,i);
201 if ((methodId == -1)||(idList.contains(new Integer(methodId)))) continue;
202 idList.add(new Integer(methodId));
203 }
204 }
205
206
207 int selection[] = null;
208
209 if ((SELECT_OPTION & 0x00f0) == 0x0010) {
210 selection = new int[idList.size()];
211 for (int i=0; i<selection.length; i++)
212 selection[i] = ((Integer)idList.get(i)).intValue();
213 } else {
214 selection = new int[entityIdFilter.getEntityNumber()];
215 for (int i=0; i<selection.length; i++)
216 selection[i] = i;
217 }
218
219 entityIdFilter.makeSelection(subjectDefinition.getType(),selection,start,end,timeMap);
220 }
221
222 protected void mouseMove(int x, int y) {
223 int X = canvas.getImageX(x);
224 int Y = canvas.getImageY(y);
225
226 if ((X>=0) && (Y >= 0)) {
227 if (image.getSortedColor(null,null,X,Y)==null)
228 Scene.setStatus(" ");
229 else
230 Scene.setStatus(getEntityName(X,Y)+" "+X+":"+Y);
231 } else {
232 Scene.setStatus(" ");
233 }
234 }
235
236 protected ArrayList createOptionalMenu() {
237 if (menuList.size() > 0) return null;
238
239 menuList.clear();
240 itemChangeThread = new JMenuItem("Switch thread...");
241 itemChangeThread.setMnemonic(KeyEvent.VK_T);
242 itemChangeThread.addActionListener(new ActionListener() {
243 public void actionPerformed(ActionEvent e) {
244 visualize();
245 }
246 });
247
248 menuList.add(itemChangeThread);
249 return menuList;
250 }
251
252 private String getEntityName(int x, int y) {
253 String returnVal = "";
254 int mappedId = (int)getEntityId(x,y);
255 Entity entity = entityIdFilter.getEntityFromInt(mappedId);
256
257 if (entity != null) returnVal = entity.getName();
258 return returnVal;
259 }
260
261 private long getEntityId(int x, int y) {
262 Color color = image.getSortedColor(null,null,x,y);
263 if ((color == null)||(painter == null)) return -1;
264 return ((RandomPainter)painter).getKeyFromColor(color);
265 }
266
267 protected void switchThread(long threadId) {
268 if (currentThread != threadId) {
269 stack = (Stack)methodStacks.get(new Long(threadId));
270 if (stack == null) {
271 stack = new Stack();
272 methodStacks.put(new Long(threadId),stack);
273 }
274 super.switchThread(threadId);
275 }
276 }
277
278 protected void installPainter() {
279 painter = new RandomPainter();
280 }
281
282 public JMenuItem[] createSelectionMenuItem() {
283 if (selectionMenu!=null) return selectionMenu;
284
285 itemSelectTimeFrame = new JCheckBoxMenuItem("Time Frame");
286 itemSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
287 itemSelectTimeFrame.addActionListener(new ActionListener() {
288 public void actionPerformed(ActionEvent e) {
289 boolean selected = itemSelectTimeFrame.isSelected();
290 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
291 }
292 });
293 itemSelectTimeFrame.setSelected(true);
294
295 itemSelectOccurredEntities = new JCheckBoxMenuItem("Occurred Entities");
296 itemSelectOccurredEntities.setMnemonic(KeyEvent.VK_O);
297 itemSelectOccurredEntities.addActionListener(new ActionListener() {
298 public void actionPerformed(ActionEvent e) {
299 boolean selected = itemSelectOccurredEntities.isSelected();
300 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
301 }
302 });
303 itemSelectOccurredEntities.setSelected(true);
304
305 selectionMenu = new JMenuItem[2];
306 selectionMenu[0] = itemSelectTimeFrame;
307 selectionMenu[1] = itemSelectOccurredEntities;
308
309 return selectionMenu;
310 }
311
312 protected JPanel createConfigurationPanel() {
313 JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5));
314 JPanel panelEvent = new JPanel(new GridLayout(2,2));
315
316 Box panelBottom = new Box(BoxLayout.Y_AXIS);
317 returnVal.add(panelBottom);
318
319 textBegin = new JTextField(String.valueOf(beginCall));
320 textEnd = new JTextField(String.valueOf(endCall));
321 panelEvent.add(new JLabel("From Call No:"));
322 panelEvent.add(textBegin);
323
324 toEventNo = new JLabel("To Call No:");
325 panelEvent.add(toEventNo);
326 panelEvent.add(textEnd);
327 panelBottom.add(panelEvent);
328
329 return returnVal;
330 }
331
332 protected void updateComboSubject() {
333 super.updateComboSubject();
334 String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName()));
335 toEventNo.setText("To Call No:("+range+")");
336 }
337
338 public Object clone() {
339 StackViz o = (StackViz)super.clone();
340 o.dimension[0] = o.xAxis;
341 o.dimension[1] = o.entityIdFilter;
342 o.dimension[2] = o.filter2;
343
344
345 o.td = new ThreadChooser(o.imageMap,false);
346
347 o.methodStacks = new HashMap();
348 Iterator it = methodStacks.keySet().iterator();
349 while (it.hasNext()) {
350 Object key = it.next();
351 Stack newStack = new Stack(), oldStack = (Stack)methodStacks.get(key);
352 o.methodStacks.put(key,newStack);
353 for (int i=0; i<oldStack.size(); i++)
354 newStack.add(oldStack.get(i));
355 }
356
357 o.menuList = new ArrayList();
358 o.createDialog();
359 return o;
360 }
361
362 }